As used in application servers, virtual machines and other type of computer servers, a classloader is a fundamental module of the Java language. The classloader runs as part of the Java virtual machine (JVM) to load software classes into the memory of the computer. The classloader is then responsible for finding and loading class files at run time in response to requests from applications.
Classloaders are typically deployed in a hierarchy with parent and child classloaders. The relationship between parent and child classloaders is analogous to the object relationship between superclasses and subclasses.
Within the classloader hierarchy, a bootstrap classloader provides the root of the Java hierarchy. The Java virtual machine (JVM) creates the bootstrap classloader, which loads the Java development kit (JDK) internal classes and java.* packages included in the JVM. (For example, the bootstrap classloader loads java.lang.String).
An extensions classloader is a child of the bootstrap classloader. The extensions classloader loads Java Archive (JAR) files placed in the extensions directory of the JDK, and allows for extending the JDK without adding entries to the classpath. Anything placed in the extensions directory is self-contained and can only refer to classes in the extensions directory or to JDK classes.
A system classpath classloader extends the extensions classloader. The system classpath classloader loads the classes from the classpath of the JVM. The term “system classloader” is used herein to differentiate this level of classloaders from other classloaders that are related to J2EE applications (which are referred to herein as “application classloaders”; it will be noted however that some other computer systems and environments refer to the system level classpath classloader as the application classloader).
A plurality of application-specific classloaders, or application classloaders are children of the system classpath classloader.
Classloaders use a delegation model when loading a class. In a typical implementation, the classloader implementation first checks its cache to see if the requested class has already been loaded. This class verification improves performance in that its cached memory copy can be used instead of repeated loading of the class from disk. If the class is not found in its cache, then the current classloader asks its parent in the hierarchy for that class. If the parent cannot load the class, then the classloader attempts to load the class. If a class exists in both the parent and the child classloaders, then the parent version is the one that is loaded. This delegation model is often followed to avoid multiple copies of the same form being loaded, which could lead to a ClassCastException.
Typically, the classloader hierarchy is defined in a configuration file for each application to be deployed to a server or application server. (For example, in WebLogic Server, the configuration information can be stored in a weblogic-application.xml file). The server reads the information in the configuration file and automatically creates the corresponding hierarchy of classloaders when the application is deployed. FIG. 1 shows a typical application classloading environment 10, including a system classloader 12 and an application classloader 14. The root classloader in this hierarchy can load any EJB JAR files 16 into the application. The server can also create a child classloader 18, 20 for each Web application WAR file. Since it is common for Web applications to call EJBs, the application classloader architecture typically allows JavaServer Page (JSP) files and servlets 22, 24 to see the EJB interfaces in their parent classloader. This also allows Web applications to be redeployed without redeploying the entire EJB tier.
However, while the typical classloader hierarchy does provide benefits, including e.g. allowing an application developer to used third-party JAR files such as ANTLR, Xerxes, SAML, and other proprietary and open source JARs, it also suffers from limitations. For example, it is not possible for the application developer to simultaneously use different versions of those JARs for different applications because the delegation model won't allow it. Furthermore, the Java 2 delegation model specifies that a classic loader must ask it's parent for a particular class before it tries to load that class itself. So for an application to load, e.g., a different copy of Xerxes, the application classloader must make a request to the system classloader first. The application can't load a version other than the Xerxes classloader specified at the system level.